#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdlib>

using namespace std;

// 3、通过信号等待子进程退出
// 子进程在退出时候会发出17号信号
void handler(int signo)
{
    pid_t ret;
    sleep(5);
    while ((ret = waitpid(-1, NULL, WNOHANG)) > 0)
    {
        cout << "catch a signo " << signo << " quit childpid: " << ret << endl;
    }
    // exit(0);
}
int main()
{
    signal(17, handler);

    // signal(17, SIG_DFL); //将17号信号设置为忽略，这样子进程退出就不需要等待回收了

    for (int i = 0; i < 10; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            while (true)
            {
                cout << "I am a child pid: " << getpid() << " ppid: " << getppid() << endl;
                sleep(5);
                break;
            }
            cout << "chile quie" << endl;
            exit(0);
        }
        // sleep(1);
    }

    while (true)
    {
        cout << "I am father process " << getpid() << endl;
        sleep(1);
    }
    return 0;
}

// 1、volatile关键字使用
//  volatile bool flag = 0;//volatite 使代码在编译的时候不优化，内存可见
//  void handler(int signo)
//  {
//      flag = 1;
//      cout << "catch a signo :" << signo << endl;
//  }
//  int main()
//  {
//      signal(2, handler);
//      while (!flag)//编译器默认是O0不优化，如果优化的话，cpu检测到main函数没有对flag进行改变，因此会直接将flag变量
//      {              //加载至寄存器，之后一直在寄存器内左逻辑运算，不再从内存获取
//      }
//      cout << "process quit" << endl;
//  }

// 2、sigaction使用
//  void Printpending()
//  {
//      sigset_t pending;
//      sigpending(&pending);
//      for (int i = 1; i < 31; i++)
//      {
//          if (sigismember(&pending, i))
//          {
//              cout << "1";
//          }
//          else
//          {
//              cout << "0";
//          }
//      }
//      cout << "\n\n";
//  }
//  // 测试信号在递达前将pending由1->0还是在递达后将pending由1->0(信号在递达前就完成了转化)
//  // 并且信号在递达未完成前，会将该信号block位图置为1进行阻塞，结束后置0；
//  void handler(int signo)
//  {

//     cout << "I get a signo " << signo << endl;
//     while (true)
//     {
//         Printpending();
//         sleep(1);
//     }
// }

// int main()
// {
//     struct sigaction act, oact;
//     memset(&act, 0, sizeof(act));
//     memset(&oact, 0, sizeof(oact));
//     act.sa_handler = handler;
//     sigaction(2, &act, &oact);

//     sigemptyset(&act.sa_mask); // sigset_t mask 信号在处理过程中，阻塞位图
//     sigaddset(&act.sa_mask, 1);
//     sigaddset(&act.sa_mask, 3);
//     sigaddset(&act.sa_mask, 4);
//     sigprocmask(SIG_SETMASK, &act.sa_mask, &oact.sa_mask);
//     while (true)
//     {
//         cout << "I am  process " << getpid() << endl;
//         sleep(1);
//     }
// }